標題:Vercel + Upstash Redis 授權驗證系統完整實作指南:從混亂到成功的真實歷程
描述:詳細記錄 2025 年實際部署過程中遇到的環境變數混亂、連接問題及完整解決方案,包含序號驗證系統的完整實作
最後更新:2025-08-19
版本:v1.0
作者:rj0217
來源:COVIA官方知識
Vercel + Upstash Redis 授權驗證系統完整實作指南
前言
在 2025 年 8 月,實際部署 Vercel + Upstash Redis 授權系統時,發現官方文檔與實際操作存在顯著差異。本文記錄完整的問題診斷與解決過程,幫助遇到相同問題的開發者。
專案背景
- 目標:為桌面應用程式建立雲端授權驗證系統
- 技術棧:Vercel Functions + Upstash Redis
- 需求:序號生成、驗證、硬體綁定、切換限制
第一部分:環境設置
1.1 安裝 Vercel CLI
# 全域安裝 Vercel CLI
npm install -g vercel
# 如果遇到 'vercel' 不是內部或外部命令錯誤
# 確認全域安裝成功
1.2 初始化 Vercel 專案
cd your-api-directory
vercel
# 登入流程
> Continue with Google
> Set up and deploy "~/your-api-directory"? yes
> Which scope? [選擇你的帳號]
> Link to existing project? no
> Project name? your-license-api
> In which directory is your code? ./
> Want to modify settings? no
第二部分:Upstash Redis 設置(關鍵問題區)
2.1 創建 Upstash Redis 資料庫
- 進入 Vercel Dashboard → Storage
- 選擇 Upstash → Serverless Redis
- 設定選項:
- Primary Region: Asia Pacific (Tokyo)
ap-northeast-1
- Eviction: 禁用(重要!序號不能被自動刪除)
- Plan: Free(開始測試用)
- Primary Region: Asia Pacific (Tokyo)
2.2 環境變數混亂問題
🔴 實際遇到的問題
Vercel 自動產生的環境變數名稱與預期不符:
預期的變數名稱:
- UPSTASH_REDIS_REST_URL
- UPSTASH_REDIS_REST_TOKEN
實際產生的變數名稱:
- UPSTASH_REDIS_REST_KV_REST_API_URL
- UPSTASH_REDIS_REST_KV_REST_API_TOKEN
- UPSTASH_REDIS_REST_KV_URL(Redis 連接字串)
- UPSTASH_REDIS_REST_REDIS_URL(重複)
🟢 解決方案
方案一:修改程式碼(推薦)
修改 lib/redis.js
:
import { Redis } from '@upstash/redis';
// 使用 Vercel 實際產生的環境變數名稱
const redis = new Redis({
url: process.env.UPSTASH_REDIS_REST_KV_REST_API_URL,
token: process.env.UPSTASH_REDIS_REST_KV_REST_API_TOKEN,
});
export default redis;
方案二:手動設定環境變數
在 Vercel Environment Variables 中新增映射:
- 複製實際的 URL 和 Token 值
- 創建符合程式碼預期的變數名稱
2.3 識別正確的值
從 Upstash 提供的多個值中,如何識別正確的 REST API 憑證:
值的類型 | 格式特徵 | 用途 |
---|---|---|
REST URL | https://xxx-xxx-12345.upstash.io | ✅ 使用這個 |
REST Token | 50-60 字元,通常以 A 開頭 | ✅ 使用這個 |
Redis URL | rediss://default:xxx@xxx:6379 | ❌ 原生連接用 |
Password | 超長字串,嵌入在連接字串中 | ❌ 不要單獨使用 |
範例值格式(已匿名化):
// 正確的 REST API 設定範例
const redis = new Redis({
url: 'https://example-name-12345.upstash.io',
token: 'AxxxAAIncDExxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
});
第三部分:API 實作
3.1 專案結構
your-api-directory/
├── api/
│ ├── generate.js # 生成序號 API
│ ├── verify.js # 驗證序號 API
│ └── status.js # 查詢狀態 API
├── lib/
│ └── redis.js # Redis 連接模組
├── package.json
└── vercel.json
3.2 序號驗證邏輯
驗證 API 需要兩個參數:
serial
: 序號(格式:PREFIX-XXXX-XXXX)hwid
: 硬體識別碼
特點:
- 首次驗證會綁定 HWID
- 每天允許切換 3 次裝置
- 記錄所有切換歷史
3.3 測試命令
# 測試 API 首頁
curl https://your-license-api.vercel.app
# 生成序號(需要 ADMIN_KEY)
curl -X POST https://your-license-api.vercel.app/api/generate \
-H "Content-Type: application/json" \
-d "{\"admin_key\":\"YOUR_SECRET_ADMIN_KEY\",\"count\":1,\"days\":30}"
# 驗證序號(需要 hwid)
curl -X POST https://your-license-api.vercel.app/api/verify \
-H "Content-Type: application/json" \
-d "{\"serial\":\"PREFIX-XXXX-XXXX\",\"hwid\":\"TEST-MACHINE-001\"}"
第四部分:Upstash 設定建議
4.1 Eviction(驅逐機制)設定
對於授權驗證系統,必須禁用 Eviction。
設定 | 意思 | 適用場景 |
---|---|---|
啟用 | 資料庫滿了自動刪除舊資料 | 快取、Session |
禁用 | 資料庫滿了拒絕新寫入 | 序號驗證(推薦) |
4.2 容量規劃
免費方案分析:
- 儲存空間: 256MB(可存約 100 萬筆序號)
- 每月命令: 500,000 次
- 計算公式: 用戶數 × 每日啟動次數 × 30 天
成長路徑建議:
- Free: 開發測試(< 5,000 用戶)
- Pay as You Go: 用戶增長期
- Fixed: 穩定高流量(> 550 萬次/月)
第五部分:常見問題與解決
5.1 PowerShell 命令錯誤
# 錯誤寫法
curl -Method POST url -Body "data"
# 正確寫法
Invoke-RestMethod -Uri "url" -Method POST -ContentType "application/json" -Body 'data'
# 或
curl.exe -X POST url -H "Content-Type: application/json" -d "data"
5.2 環境變數未生效
檢查清單:
- 確認 Environment Variables 已儲存
- 已重新部署(Redeploy)
- 變數名稱與程式碼一致
- 檢查 Vercel Functions 日誌
5.3 Redis 連接失敗
診斷步驟:
- 檢查 Storage 連接狀態
- 確認環境變數存在
- 驗證 URL 格式(必須是 https://)
- 確認 Token 正確(不是密碼)
第六部分:整合到應用程式
6.1 Python 整合範例
import requests
import hashlib
import platform
def get_hwid():
"""生成硬體識別碼"""
machine = platform.machine() + platform.node()
return hashlib.md5(machine.encode()).hexdigest()
def verify_license(serial):
"""驗證授權"""
hwid = get_hwid()
response = requests.post(
"https://your-license-api.vercel.app/api/verify",
json={"serial": serial, "hwid": hwid}
)
return response.json()
# 使用範例
result = verify_license("PREFIX-XXXX-XXXX")
if result["valid"]:
print(f"授權有效,剩餘 {result['days_left']} 天")
else:
print(f"授權無效:{result.get('error')}")
6.2 成功回應範例
// 生成序號成功
{
"success": true,
"count": 1,
"serials": [{
"serial": "PREFIX-XXXX-XXXX",
"expires_at": "2025-09-17T21:51:32.545Z",
"days": 30
}],
"message": "成功生成 1 個序號"
}
// 驗證成功
{
"valid": true,
"expires_at": "2025-09-17T21:51:32.545Z",
"days_left": 30,
"message": "驗證成功"
}
// 裝置切換成功
{
"valid": true,
"expires_at": "2025-09-17T21:51:32.545Z",
"days_left": 30,
"message": "裝置切換成功",
"switch_count_today": 1
}
第七部分:安全建議
-
保護 ADMIN_KEY
- 使用強密碼(建議格式:
APP2025-Admin-[隨機字串]
) - 定期更換
- 不要硬編碼在客戶端
- 使用環境變數儲存
- 使用強密碼(建議格式:
-
監控異常
- 追蹤頻繁切換的序號
- 設定使用量警報
- 定期備份序號清單
-
擴充考量
- 實作黑名單機制
- 加入 IP 限制
- 建立管理後台
總結
本指南記錄了從環境變數混亂到成功部署的完整過程。關鍵要點:
- Vercel 自動產生的環境變數名稱可能與預期不符
- Upstash 提供多種連接方式,需識別正確的 REST API 憑證
- 序號驗證系統必須禁用 Eviction 以防資料遺失
- HWID 綁定提供彈性但安全的授權機制
透過本文的實戰經驗,希望能幫助開發者避免相同的陷阱,快速建立可靠的授權系統。
參考資源
文檔迭代紀錄
協作夥伴戳記
2025/08/19 Claude Opus 4.1 ab20ff42-e5ef-485d-9791-8ba709d2f2a7
2025/08/19 Gemini 2.5 pro [Eviction 機制詳解貢獻]
2025/08/19 Claude Code [本地程式碼修正協作]